package gin.dev.update;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.PowerManager;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;

public class DownloadTask extends AsyncTask<String, Integer, String> {

	public static String TAG = "Download test";
	public static int DOWNLOAD_COMPLETE = -1;
	public static int DOWNLOAD_CANCEL = -2;
	public static int DOWNLOAD_ERROR = -3;
	
	private Context context;
	private PowerManager.WakeLock mWakeLock;
	private ProgressBar mProgressDialog;
	public int progressValue = 0;
	
	public IOnDownload mDownloadedAction;
	public IOnInstalled mInstalledAction;

	public DownloadTask(Context context, ProgressBar pd, IOnDownload downloaded) {
		this.context = context;
		mProgressDialog = pd;
		mDownloadedAction = downloaded;
	}
	
	public void ChangeProgressBar(ProgressBar pb)
	{
		mProgressDialog = pb;
		pb.setVisibility(View.VISIBLE);
	}
	
	public boolean IsFinished()
	{
		if(progressValue < 0)
			return true;
		return false;
	}

	@Override
	protected String doInBackground(String... sUrl) {
		
		Log.i(TAG, sUrl[0]);
		InputStream input = null;
		OutputStream output = null;
		HttpURLConnection connection = null;
		String packageName = sUrl[1];
		try {
			URL url = new URL(sUrl[0]);
			connection = (HttpURLConnection) url.openConnection();
			connection.connect();

			// expect HTTP 200 OK, so we don't mistakenly save error report
			// instead of the file
			if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
				return "Server returned HTTP " + connection.getResponseCode()
						+ " " + connection.getResponseMessage();
			}

			// this will be useful to display download percentage
			// might be -1: server did not report the length
			int fileLength = connection.getContentLength();

 			// download the file
			input = connection.getInputStream();
			String path = Environment.getExternalStorageDirectory()
					.getAbsolutePath() + "/Download/" + packageName + ".apk";
			output = new FileOutputStream(path);

			byte data[] = new byte[4096];
			long total = 0;
			int count;
			while ((count = input.read(data)) != -1) {
				// allow canceling with back button
				if (isCancelled()) {
					input.close();
					return null;
				}
				total += count;
				// publishing the progress....
				if (fileLength > 0) // only if total length is known
					publishProgress((int) (total * 100 / fileLength));
				output.write(data, 0, count);
			}
		} catch (Exception e) {
			progressValue = DOWNLOAD_ERROR;
			Toast.makeText(context, "Download error: " + e.toString(), 10000).show();
			return null;
		} finally {
			try {
				if (output != null)
					output.close();
				if (input != null)
					input.close();
			} catch (IOException ignored) {
			}

			if (connection != null) {
				connection.disconnect();
			}
		}
		return packageName;
	}

	@Override
	protected void onPreExecute() {
		super.onPreExecute();
		// take CPU lock to prevent CPU from going off if the user
		// presses the power button during download
		PowerManager pm = (PowerManager) context
				.getSystemService(Context.POWER_SERVICE);
		mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass()
				.getName());
		mWakeLock.acquire();
		if(mProgressDialog != null)
			mProgressDialog.setVisibility(View.VISIBLE);;
	}

	@Override
	protected void onProgressUpdate(Integer... progress) {
		super.onProgressUpdate(progress);
		// if we get here, length is known, now set indeterminate to false
		progressValue = progress[0];
		if(mProgressDialog != null)
		{
			mProgressDialog.setIndeterminate(false);
			mProgressDialog.setMax(100);
			mProgressDialog.setProgress(progress[0]);			
		}
	}

	@Override
	protected void onCancelled() {
		// TODO Auto-generated method stub
		super.onCancelled();
		progressValue = DOWNLOAD_CANCEL;
		if(mProgressDialog != null)
		{
			mProgressDialog.setVisibility(View.INVISIBLE);
		}
	}

	@Override
	protected void onPostExecute(String result) {
		progressValue = DOWNLOAD_COMPLETE;
		mWakeLock.release();
		if(mProgressDialog != null)
			mProgressDialog.setVisibility(View.INVISIBLE);
		if (result != null) {
			Toast.makeText(context, "Download finished: " + result, 2000).show();
			Log.i("test", result);
			Toast.makeText(context, "File downloaded", Toast.LENGTH_SHORT)
					.show();
		}
		
		if(mDownloadedAction != null)
		{
			mDownloadedAction.OnFinished();
		}
	}
}
